package client.calendar;

import java.awt.Color;
import java.awt.Graphics;
import java.util.Calendar;
import java.util.Iterator;


import miscellaneous.Storage;
import data.Appointment;
import data.Invite;
import data.Meeting;
import data.Message;
import data.User;
import data.room.Reservation;

/**
 * Draws an appointment on a graphics object in the correct position.
 * @author Erik
 *
 */
public class AppointmentGraphics {
	
	private int secondsPerRow;					//milliseconds in each row of the calendar, 3600 == 1 hour
	private int columnWidth;					//width of each column in pixels
	private int rowHeight;						//height of each row in pixels
	private int beginHour;						//the first hour of the day
	private Calendar cal;						//calendar giving the first day to be displayed in the canvas
	private User user;							//the owner of the appointments and meetings to display
	
	/**
	 * Initializes the drawer
	 * @param columnWidth The width in pixels of each column
	 * @param rowHeight The height in pixels of each row
	 * @param secondsPerRow The number of seconds in each row
	 * @param beginHour The first hour of the day, i.e. the first displayed hour
	 * @param calendar A calendar set to the first day displayed on the calendar
	 */
	public AppointmentGraphics(int columnWidth, int rowHeight, int secondsPerRow, int beginHour, Calendar calendar, User user) {

		this.columnWidth = columnWidth;
		this.rowHeight = rowHeight;
		this.secondsPerRow = secondsPerRow;
		this.beginHour = beginHour;
		this.cal = calendar;
		this.user = user;
	}
	
	
	/**
	 * Draws the supplied appointment on the graphics object.
	 * @param g The graphics object to draw on
	 * @param app The appointment to draw
	 */
	public void draw(Graphics g, Appointment app) {
		int x = this.getX(app);
		int y = this.getY(app);
		
		Reservation res = app.getReservation();
		
		int height = getHeight(app);
		
		Color outline = null,fill = null;
		if(app instanceof Meeting) {
			for(Iterator<Message> it = Storage.messages.iterator(); it.hasNext(); ) {
				Message msg = it.next();
				if(msg instanceof Invite && msg.getMeeting() == app && msg.getReceiver() == user && ((Invite)msg).getAnswer() == Invite.ANSWER_UNKOWN) {
					outline = Storage.colorMeetingOutlineNotAnswered;
					fill = Storage.colorMeetingFillNotAnswered;
					break;
				}
			}
			if(outline == null) {
				outline = Storage.colorMeetingOutlineAnswered;
				fill = Storage.colorMeetingFillAnswered;
			}
		}
		else {
			outline = Storage.colorAppointmentOutline;
			fill = Storage.colorAppointmentFill;
		}
		int arcRadius = Storage.rectangleArcRadius;
		g.setColor(fill);
		g.fillRoundRect(x+1, y+1, columnWidth-1, height-1, arcRadius, arcRadius);

		g.setColor(outline);
		g.drawRoundRect(x+2, y+2, columnWidth-3, height-3, arcRadius, arcRadius);
		
		
		g.setColor(Color.black);
		x += 10;
		y += 20;
		g.drawString(app.getTitle(), x, y);
		y+=20;
		if(res.getRoom() != null)
			g.drawString(res.getRoom().getName(), x, y);
			y += 20;

	}

	
	/**
	 * Returns the height, in pixels, of the appointments as drawn on screen
	 * @param app The appointment
	 * @return The height 
	 */
	public int getHeight(Appointment app) {
		int duration = (int) ( (app.getReservation().getEndTime().getTimeInMillis() - 
						app.getReservation().getStartTime().getTimeInMillis()) / 1000);
		int height = (int) (1.0 * duration / secondsPerRow * rowHeight);
		
		return height;
	}
	
	
	/**
	 * Returns the width of the appointment as drawn on screen
	 * @param app Any appointment
	 * @return The width of the appointment
	 */
	public int getWidth(Appointment app) {
		return columnWidth;
	}
	
	/** 
	 * Get the x-coordinate the appointment should be drawn on.
	 * @param app The appointment
	 * @return The x-coordinate
	 */
	public int getX(Appointment app) {
		Calendar eventDate = app.getReservation().getStartTime();
		
		// calculate the x-coordinate
		int eventDay = eventDate.get(Calendar.DAY_OF_WEEK);
		int offset = eventDay - cal.get(Calendar.DAY_OF_WEEK);
		if(offset < 0)
			offset += 7;

		int x = offset * columnWidth;
		
		return x;
	}
	
	/**
	 * Get the y-coordinate the appointment should be drawn on.
	 * @param app The appointment
	 * @return The y-coordinate
	 */
	public int getY(Appointment app) {
		Calendar eventDate = app.getReservation().getStartTime();
		
		//number of seconds after the start of the day the event begins
		int eventSecond = eventDate.get(Calendar.SECOND) + 
		eventDate.get(Calendar.MINUTE)*60 + 
		eventDate.get(Calendar.HOUR_OF_DAY)*3600;
		
		//number of seconds since start of the day the calendar begins
		int beginSecond = beginHour * 3600;
		
		//if the event 
		if( eventSecond < beginSecond)
			beginSecond -= 3600 * 24;
		int y = (int) (1.0 * (eventSecond - beginSecond) * rowHeight / secondsPerRow);
		
		return y;
	}
	
}
